package com.xiaoniu.lib_keleim.db.manager;

import android.app.Application;
import android.os.Handler;
import android.os.Looper;

import com.xiaoniu.lib_keleim.pojo.vos.UserInfoVO;
import com.xiaoniu.lib_keleim.db.ConversationListCallBack;
import com.xiaoniu.lib_keleim.db.MessageListCallBack;
import com.xiaoniu.lib_keleim.pojo.vos.BaseMessage;
import com.xiaoniu.lib_keleim.pojo.vos.MessageConversationVO;
import com.xiaoniu.lib_keleim.pojo.dos.ConversationEntity;
import com.xiaoniu.lib_keleim.pojo.dos.MessageEntity;
import com.xiaoniu.lib_keleim.pojo.dos.UserEntity;
import com.xiaoniu.lib_keleim.pojo.vos.WrapperConversation;
import com.xiaoniu.lib_keleim.utils.GsonUtil;
import com.xiaoniu.lib_keleim.utils.LogUtils;

import java.util.ArrayList;
import java.util.List;

import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmResults;
import io.realm.Sort;

public class DBDaoManagerImpl implements IDBDaoManager{

    private Realm mRealmDao;
    private final String TAG = "DBDaoManagerImpl";
    private Handler mHandler = new Handler(Looper.myLooper());
    @Override
    public void initDB(Application application) {
        Realm.init(application);
        String realmName = "imdb.realm";
        RealmConfiguration config = new RealmConfiguration.Builder()
                .name(realmName)
                .allowWritesOnUiThread(true)
                .migration(new MyMigration())
                .build();

        mRealmDao = Realm.getInstance(config);
    }

    @Override
    public void updateUserEntity(UserInfoVO entity) {
        if (entity==null || mRealmDao==null) {
            return;
        }
        mRealmDao.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                UserEntity user = new UserEntity();
                user.customerId = entity.customerId;
                user.nickName = entity.nickName;
                user.headPortraitUrl = entity.headPortraitUrl;
                realm.insertOrUpdate(user);
            }
        });
    }

    @Override
    public void updateUserEntity(UserEntity entity) {
        if (entity==null || mRealmDao==null) {
            return;
        }
        mRealmDao.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
//                UserEntity user = new UserEntity();
//                user.customerId = entity.customerId;
//                user.nickName = entity.nickName;
//                user.headPortraitUrl = entity.headPortraitUrl;
                realm.insertOrUpdate(entity);
            }
        });
    }

    @Override
    public UserEntity getUserEntity(long customerId) {
        UserEntity userEntity = null;
        if (customerId <= 0) {
            return userEntity;
        }
        try {
            userEntity = mRealmDao.where(UserEntity.class).equalTo("customerId", customerId).findFirst();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return userEntity;
    }

    @Override
    public void updateMessageEntity(BaseMessage entity) {
        if (entity==null) {
            return;
        }
        mRealmDao.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.insertOrUpdate(entity.toMessageEntity());
                if (entity.sendUser!=null) {
                    realm.insertOrUpdate(entity.sendUser);
                }
            }
        });
    }

    @Override
    public void insertIncomingMessage(BaseMessage entity) {
        updateMessageEntity(entity);
    }

    @Override
    public void insertOutgoingMessage(BaseMessage entity) {
        updateMessageEntity(entity);
    }

    @Override
    public void deleteMessages(long messageId) {
        if (messageId==0) {
            return;
        }
        mRealmDao.executeTransactionAsync(realm -> {
            MessageEntity message = realm.where(MessageEntity.class).equalTo("messageId", messageId).findFirst();
            if (message!=null) {
                message.deleteFromRealm();
            }
        });
    }

    @Override
    public void deleteConversation(long targetId) {
        if (targetId==0) {
            return;
        }
        mRealmDao.executeTransactionAsync(realm -> {
            ConversationEntity conversationEntity = realm.where(ConversationEntity.class).equalTo("conversationId", targetId).findFirst();
            if (conversationEntity!=null) {
                conversationEntity.deleteFromRealm();
            }
        });
    }


    @Override
    public void updateMessageEntityArray(List<BaseMessage> entity) {
        if (entity==null) {
            return;
        }
        mRealmDao.executeTransactionAsync(realm -> {
            for (BaseMessage datum : entity) {
                if (datum==null) {
                    continue;
                }
                realm.insertOrUpdate(datum.toMessageEntity());
            }
        });
    }

    @Override
    public void updateConversationEntity(MessageConversationVO entity) {
        if (entity==null) {
            return;
        }
        mRealmDao.executeTransactionAsync(realm -> {
            realm.insertOrUpdate(entity.toMessageConversationEntity());
            LogUtils.d("insertMessageConversation 完成");
        });
    }

    @Override
    public void updateConversationEntityArray(List<MessageConversationVO> entity) {
        if (entity==null) {
            return;
        }
        mRealmDao.executeTransactionAsync(realm -> {
            for (MessageConversationVO datum : entity) {
                if (datum==null) {
                    continue;
                }
                realm.insertOrUpdate(datum.toMessageConversationEntity());
            }
            LogUtils.d("insertMessageConversationArray 完成");
        });
    }

    @Override
    public void getConversationListByPage(long timeStamp, final int count, ConversationListCallBack callback) {
        mRealmDao.executeTransactionAsync(realm -> {
            if (callback!=null) {
                long customerId = UserInfoVO.getSingleton().getCustomerId();
                RealmResults<ConversationEntity> allConversationList = realm
                        .where(ConversationEntity.class)
                        .equalTo("targetId",customerId)
                        .or()
                        .equalTo("userId",customerId)
                        .sort("lastMessageId", Sort.DESCENDING)
                        .findAll();
                ArrayList<MessageConversationVO> messageConversationVOS = new ArrayList<>();
                for (ConversationEntity conversationEntity : allConversationList) {
                    messageConversationVOS.add(realm.copyFromRealm(conversationEntity).toMessageConversationVO());
                }
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        WrapperConversation wrapperConversation = new WrapperConversation();
                        wrapperConversation.fromLocal = true;
                        wrapperConversation.conversations = messageConversationVOS;
                        callback.onResult(wrapperConversation);
                    }
                });
                LogUtils.d("queryMessageConversationArray 完成");
            }
        });
    }

    @Override
    public void getHistoryMessages(long targetId, long timeStamp, final int count, MessageListCallBack callback) {
        mRealmDao.executeTransactionAsync(realm -> {
            if (callback!=null) {
                RealmResults<MessageEntity> allMessageList = realm
                        .where(MessageEntity.class)
                        .equalTo("userId", UserInfoVO.getSingleton().getCustomerId())
                        .and()
                        .equalTo("targetId", targetId)
                        .or()
                        .equalTo("userId", targetId)
                        .and()
                        .equalTo("targetId", UserInfoVO.getSingleton().getCustomerId())
                        .sort("timestamp", Sort.ASCENDING)
                        .findAll();
                ArrayList<BaseMessage> messageConversationVOS = new ArrayList<>();
                for (MessageEntity messageEntity : allMessageList) {
                    messageConversationVOS.add(realm.copyFromRealm(messageEntity).toMessageChatVO());
                }
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        callback.onResult(messageConversationVOS);
                    }
                });
                LogUtils.d("queryMessageEntityArray完成 "+ GsonUtil.toJson(messageConversationVOS));
            }
        });
    }
}
